﻿using Sustainalytics.ClientDW.Synchronization.SyncESGData.AbstractClassesAndInterfaces;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.CorporateDataLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.EsgResearchProfileLogic;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Sustainalytics.SharedEntities.EsgResearch;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.AnalystLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.ESGAssessmentThresholdLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.SubPeerGroupKeyIssueLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.IndicatorTemplateLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.SourceLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.CompanyKeyESGIssueLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.CompanyWeightsLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.RPCompanyESGComputationResultLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.RPCompanyProfileLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.RPIndicatorExtendedLogic;

namespace Sustainalytics.ClientDW.Synchronization.SyncESGData
{
    public class ComprehensiveEsgSync
    {
        private readonly IComprehensiveEsgCompaniesIdsQuery comprehensiveEsgCompaniesIdsQuery;
        private readonly IComprehensiveEsgResearchProfileQuery comprehensiveEsgResearchProfileQuery;
        private readonly IComprehensiveEsgSyncOrchestrator<Analyst> analystOrchestrator;
        private readonly IComprehensiveEsgSyncOrchestrator<EsgResearchProfile> companyKeyESGIssueOrchestrator;
        private readonly IComprehensiveEsgSyncOrchestrator<EsgResearchProfile> comprehensiveCompanyWeightsOrchestrator;
        private readonly ICorporateDataComprehensiveEsgProcessor corporateDataComprehensiveEsgProcessor;
        private readonly IComprehensiveEsgSyncOrchestrator<EsgAssessmentThreshold> esgAssessmentThresholdOrchestrator;
        private readonly IComprehensiveEsgSyncOrchestrator<EsgResearchProfile> comprehensiveEsgResearchProfileOrchestrator;
        private readonly IComprehensiveEsgSyncOrchestrator<IndicatorTemplate> indicatorTemplateOrchestrator;
        private readonly List<IndicatorTemplate> indicatorTemplates;
        private readonly IComprehensiveEsgSyncOrchestrator<EsgResearchProfile> comprehensiveRPCompanyESGComputationResultOrchestrator;
        private readonly IComprehensiveEsgSyncOrchestrator<EsgResearchProfile> comprehensiveRPCompanyProfileOrchestrator;
        private readonly IComprehensiveEsgSyncOrchestrator<EsgResearchProfile> comprehensiveRPIndicatorExtendedOrchestrator;
        private readonly IComprehensiveEsgSyncOrchestrator<Source> sourceOrchestrator;
        private readonly IComprehensiveEsgSyncOrchestrator<KeyIssue> subPeerGroupKeyIssuesOrchestrator;        

        public ComprehensiveEsgSync(
            EsgCompaniesIdsQuery comprehensiveEsgCompaniesIdsQuery,
            EsgResearchProfileQuery comprehensiveEsgResearchProfileQuery,
            AnalystOrchestrator analystOrchestrator,
            CompanyKeyESGIssueOrchestrator companyKeyESGIssueOrchestrator,
            CompanyWeightsOrchestrator comprehensiveCompanyWeightsOrchestrator,
            CorporateDataProcessor corporateDataComprehensiveEsgProcessor,
            EsgAssessmentThresholdOrchestrator esgAssessmentThresholdOrchestrator,
            EsgResearchProfileOrchestrator comprehensiveEsgResearchProfileOrchestrator, 
            IndicatorTemplateOrchestrator indicatorTemplateOrchestrator,
            List<IndicatorTemplate> indicatorTemplates,
            RPCompanyESGComputationResultOrchestrator comprehensiveRPCompanyESGComputationResultOrchestrator,
            RPCompanyProfileOrchestrator comprehensiveRPCompanyProfileOrchestrator,
            RPIndicatorExtendedOrchestrator comprehensiveRPIndicatorExtendedOrchestrator,
            SourceOrchestrator sourceOrchestrator,            
            SubPeerGroupKeyIssueOrchestrator subPeerGroupKeyIssuesOrchestrator)
        {
            this.comprehensiveEsgCompaniesIdsQuery = comprehensiveEsgCompaniesIdsQuery;
            this.comprehensiveEsgResearchProfileQuery = comprehensiveEsgResearchProfileQuery;
            this.analystOrchestrator = analystOrchestrator;
            this.companyKeyESGIssueOrchestrator = companyKeyESGIssueOrchestrator;
            this.comprehensiveCompanyWeightsOrchestrator = comprehensiveCompanyWeightsOrchestrator;
            this.corporateDataComprehensiveEsgProcessor = corporateDataComprehensiveEsgProcessor;
            this.esgAssessmentThresholdOrchestrator = esgAssessmentThresholdOrchestrator;
            this.comprehensiveEsgResearchProfileOrchestrator = comprehensiveEsgResearchProfileOrchestrator;
            this.indicatorTemplateOrchestrator = indicatorTemplateOrchestrator;
            this.indicatorTemplates = indicatorTemplates;
            this.comprehensiveRPCompanyESGComputationResultOrchestrator = comprehensiveRPCompanyESGComputationResultOrchestrator;
            this.comprehensiveRPCompanyProfileOrchestrator = comprehensiveRPCompanyProfileOrchestrator;
            this.comprehensiveRPIndicatorExtendedOrchestrator = comprehensiveRPIndicatorExtendedOrchestrator;
            this.sourceOrchestrator = sourceOrchestrator;
            this.subPeerGroupKeyIssuesOrchestrator = subPeerGroupKeyIssuesOrchestrator;            
        }

        public async Task<int> StartAsync()
        {
            var comprehensiveEsgCompaniesIds = await comprehensiveEsgCompaniesIdsQuery.GetAsync().ConfigureAwait(false);
            var comprehensiveEsgResearchProfiles = comprehensiveEsgResearchProfileQuery.Get(comprehensiveEsgCompaniesIds.CompaniesWithActiveResearch);

            if (comprehensiveEsgResearchProfiles.Count == 0) return 0;

            await Task.WhenAll(new[]
            {
                analystOrchestrator.OrchestrateAsync(),
                subPeerGroupKeyIssuesOrchestrator.OrchestrateAsync(),
                comprehensiveCompanyWeightsOrchestrator.OrchestrateAsync(comprehensiveEsgResearchProfiles),
                esgAssessmentThresholdOrchestrator.OrchestrateAsync(),
                comprehensiveEsgResearchProfileOrchestrator.OrchestrateAsync(comprehensiveEsgResearchProfiles, comprehensiveEsgCompaniesIds.InvalidatedCompanies),
                indicatorTemplateOrchestrator.OrchestrateAsync(indicatorTemplates),
                comprehensiveRPCompanyESGComputationResultOrchestrator.OrchestrateAsync(comprehensiveEsgResearchProfiles, comprehensiveEsgCompaniesIds.InvalidatedCompanies),
                comprehensiveRPCompanyProfileOrchestrator.OrchestrateAsync(comprehensiveEsgResearchProfiles, comprehensiveEsgCompaniesIds.InvalidatedCompanies),
                comprehensiveRPIndicatorExtendedOrchestrator.OrchestrateAsync(comprehensiveEsgResearchProfiles, comprehensiveEsgCompaniesIds.InvalidatedCompanies),
                sourceOrchestrator.OrchestrateAsync()
            }).ConfigureAwait(false);

            await Task.WhenAll(new[]
            {
                companyKeyESGIssueOrchestrator.OrchestrateAsync(comprehensiveEsgResearchProfiles, comprehensiveEsgCompaniesIds.InvalidatedCompanies),
                corporateDataComprehensiveEsgProcessor.SetResearchInProgress(comprehensiveEsgCompaniesIds.CompaniesWithActiveResearch.Where(cId => comprehensiveEsgResearchProfiles.All(rp => rp.Id != cId)))
            }).ConfigureAwait(false);

            return comprehensiveEsgResearchProfiles.Count;
        }
    }
}
